/* util */
import { getExternalComponentDomainName } from '@src/util/env'
import Log from '@src/util/log'
import { importScript, loadCss } from '@src/util/dom'
import { setTimeoutError } from '@src/util/promise'

interface ComponentModule {
    id: string,
    componentUrl: string,
    styleUrl: string
}

interface ComponentModule {
  id: string;
  componentUrl: string;
  styleUrl: string;
}

enum ComponentModuleIdEnum {
  ShbPcFeComponent = 'publink_shb_pc_fe_components',
}

const externalComponentDomainName = getExternalComponentDomainName()

/** 
 * @description 外部模块时间信息
*/
const externalComponentTimeMap = {
  /** 
   * !! 这里的时间建议和 shb-paas-pc 项目中的此组件的时间保持一致，这样的话可以使用缓存。
   * -- 因为在 fe 项目中，这个组件在首页加载完成后，会延时加载组件，这样加载一次后，paas 下次加载就可以使用缓存了。
  */
  [ComponentModuleIdEnum.ShbPcFeComponent]: '2022-12-07 11:22',
}

export const modules: ComponentModule [] = [
  {
    id: 'publink-paas',
    componentUrl: '/paas/publink-paas.umd.min.js',
    styleUrl: ''
  },
  {
    id: ComponentModuleIdEnum.ShbPcFeComponent,
    componentUrl: externalComponentDomainName + '/shb-pc-fe/component/index.js?t=' + externalComponentTimeMap[ComponentModuleIdEnum.ShbPcFeComponent],
    styleUrl: ''
    // styleUrl: externalComponentDomainName + '/shb-pc-fe/component/css/index.css?t=' + externalComponentTime,
  }
]

export const httpLoadRequest = (src: string) => {
    return new Promise((resolve) => {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', src, true);
        xhr.setRequestHeader('Content-Type', 'application;charset=utf-8');
        xhr.onreadystatechange = function () {
          if (xhr.readyState == 4 && xhr.status == 200) {
            resolve(xhr.responseText);
          }
        };
        xhr.send();
    });
}


export const resolveComponent = (src:string, ComponentModuleName: string ) => {
    return httpLoadRequest(src).then((res: unknown) => {
      new Function(res as string)();
      const component = (window as any)[ComponentModuleName] as any;
      return component.default;
    });
}

export const findMduleInfo = (moduleName: string) => {
    return modules.find(item=> item.id === moduleName)
}

export const findModuleInfo = (moduleName: ComponentModuleIdEnum | string) => {
  return modules.find(item => item.id === moduleName);
};

/** 
 * @description 根据模块名称加载外部组件
 * @param {ComponentModuleIdEnum} moduleName 模块名称
 * @param {number} timeout 超时时间
 * @returns {Promise<void>}
*/
async function loadExternalComponentByModuleName(moduleName: ComponentModuleIdEnum, timeout: number = 10) {
  return setTimeoutError<void>(timeout * 1000, loadExternalComponentByModuleNameImpl(moduleName));
}

/** 
 * @description 根据模块名称加载外部组件 实现方法
 * @param {ComponentModuleIdEnum} moduleName 模块名称
*/
async function loadExternalComponentByModuleNameImpl(moduleName: ComponentModuleIdEnum) {
  
  // 没有模块名称
  if (!moduleName) {
    return Promise.reject('[error]: loadExternalComponentByModuleName function params moduleName is required')
  }
  
  const moduleInfo = findModuleInfo(moduleName)
  
  // 没有模块信息
  if (!moduleInfo) {
    return Promise.reject(`[error]: loadExternalComponentByModuleName function params moduleName ${moduleName} is not found`)
  }
  
  const { componentUrl, styleUrl, id } = moduleInfo;
  
  // 没有组件地址
  if (!componentUrl) {
    return Promise.reject(`[error]: loadExternalComponentByModuleName function params moduleName ${moduleName} componentUrl is not found`)
  }
  
  // 是否已经加载完成组件
  const isLoadedComponent = (window as any)[id];
  
  if (isLoadedComponent) {
    return Promise.resolve();
  }
  
  // 没有样式地址
  if (!styleUrl) {
    
    console.warn(`[warn]: loadExternalComponentByModuleName function params moduleName ${moduleName} styleUrl is not found`)
    
  } else {
    
    try {
      
      // 加载样式
      loadCss(styleUrl)
      
    } catch (error: any) {
      
      Log.error(error, loadCss.name)
      
    }
    
  }
  
  // 加载组件
  return importScript(componentUrl)
  
}

export {
  loadExternalComponentByModuleName,
  ComponentModuleIdEnum
}
